package com.cucheng.chatroom.service.impl;

import java.text.MessageFormat;
import java.util.Iterator;
import java.util.Map.Entry;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.cucheng.chatroom.model.po.GroupInfo;
import com.cucheng.chatroom.model.vo.ResponseJson;
import com.cucheng.chatroom.service.ChatService;
import com.cucheng.chatroom.service.GroupInfoService;
import com.cucheng.chatroom.util.ChatType;
import com.cucheng.chatroom.util.Constant;

import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.websocketx.TextWebSocketFrame;

@Service
public class ChatServiceImpl implements ChatService {

    private static final Logger LOGGER = LoggerFactory.getLogger (ChatServiceImpl.class);
    @Autowired
    private GroupInfoService    groupInfoService;

    /**
     *@Description: TODO(用户登录后注册到全局变量，为在线用户) 
     *@Author: wangchengjie
     *@Since: 2019年3月29日下午4:22:50
     *@param param
     *@param ctx
     */
    @Override
    public void register(JSONObject param,ChannelHandlerContext ctx){
        String userId = null;
        try {
            userId = (String) param.get ("userId");
            Constant.onlineUserMap.put (userId, ctx);
            String responseJson = new ResponseJson ().success ().setData ("type", ChatType.REGISTER).toString ();
            sendMessage (ctx, responseJson);
        } catch (Exception e) {
            e.printStackTrace ();
            LOGGER.error (e.getMessage ());
        }
        LOGGER.info (MessageFormat.format ("userId为 {0} 的用户登记到在线用户表，当前在线人数为：{1}", userId, Constant.onlineUserMap.size ()));
    }

    /**
     *@Description: TODO(发送个人消息) 
     *@Author: wangchengjie
     *@Since: 2019年3月29日下午4:23:27
     *@param param
     *@param ctx
     */
    @Override
    public void singleSend(JSONObject param,ChannelHandlerContext ctx){
        try {
            String fromUserId = (String) param.get ("fromUserId");
            String toUserId = (String) param.get ("toUserId");
            String content = (String) param.get ("content");
            ChannelHandlerContext toUserCtx = Constant.onlineUserMap.get (toUserId);
            if (toUserCtx == null) {
                String responseJson = new ResponseJson ().error (MessageFormat.format ("userId为 {0} 的用户没有登录！", toUserId)).toString ();
                sendMessage (ctx, responseJson);
            } else {
                String responseJson = new ResponseJson ().success ().setData ("fromUserId", fromUserId).setData ("content", content)
                        .setData ("type", ChatType.SINGLE_SENDING).toString ();
                sendMessage (toUserCtx, responseJson);
            }
        } catch (Exception e) {
            e.printStackTrace ();
            LOGGER.error (e.getMessage ());
        }
    }

    /**
     *@Description: TODO(发送群组消息) 
     *@Author: wangchengjie
     *@Since: 2019年3月29日下午4:23:40
     *@param param
     *@param ctx
     */
    @Override
    public void groupSend(JSONObject param,ChannelHandlerContext ctx){
        try {
            String fromUserId = (String) param.get ("fromUserId");
            String toGroupId = (String) param.get ("toGroupId");
            String content = (String) param.get ("content");
            // 获取用户群组信息
            GroupInfo groupInfo = groupInfoService.getByGroupId (toGroupId);
            if (groupInfo == null) {
                String responseJson = new ResponseJson ().error ("该群id不存在").toString ();
                sendMessage (ctx, responseJson);
            } else {
                String responseJson = new ResponseJson ().success ().setData ("fromUserId", fromUserId).setData ("content", content)
                        .setData ("toGroupId", toGroupId).setData ("type", ChatType.GROUP_SENDING).toString ();
                groupInfo.getMembers ().stream ().forEach (member -> {
                    ChannelHandlerContext toCtx = Constant.onlineUserMap.get (member.getUserId ());
                    if (toCtx != null && !member.getUserId ().equals (fromUserId)) {
                        sendMessage (toCtx, responseJson);
                    }
                });
            }
        } catch (Exception e) {
            e.printStackTrace ();
            LOGGER.error (e.getMessage ());
        }
    }

    /**
     *@Description: TODO(用户退出或者掉线移除，全局变量改为离线状态) 
     *@Author: wangchengjie
     *@Since: 2019年3月29日下午4:24:31
     *@param ctx
     */
    @Override
    public void remove(ChannelHandlerContext ctx){
        try {
            Iterator<Entry<String, ChannelHandlerContext>> iterator = Constant.onlineUserMap.entrySet ().iterator ();
            while (iterator.hasNext ()) {
                Entry<String, ChannelHandlerContext> entry = iterator.next ();
                if (entry.getValue () == ctx) {
                    LOGGER.info ("正在移除握手实例...");
                    Constant.webSocketHandshakerMap.remove (ctx.channel ().id ().asLongText ());
                    LOGGER.info (MessageFormat.format ("已移除握手实例，当前握手实例总数为：{0}", Constant.webSocketHandshakerMap.size ()));
                    iterator.remove ();
                    LOGGER.info (MessageFormat.format ("userId为 {0} 的用户已退出聊天，当前在线人数为：{1}", entry.getKey (), Constant.onlineUserMap.size ()));
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace ();
            LOGGER.error (e.getMessage ());
        }
    }

    /**
     *@Description: TODO(单人发送图片，或者文件) 
     *@Author: wangchengjie
     *@Since: 2019年3月29日下午4:25:35
     *@param param
     *@param ctx
     */
    @Override
    public void FileMsgSingleSend(JSONObject param,ChannelHandlerContext ctx){
        try {
            String fromUserId = (String) param.get ("fromUserId");
            String toUserId = (String) param.get ("toUserId");
            String originalFilename = (String) param.get ("originalFilename");
            String fileSize = (String) param.get ("fileSize");
            String fileUrl = (String) param.get ("fileUrl");
            ChannelHandlerContext toUserCtx = Constant.onlineUserMap.get (toUserId);
            if (toUserCtx == null) {
                String responseJson = new ResponseJson ().error (MessageFormat.format ("userId为 {0} 的用户没有登录！", toUserId)).toString ();
                sendMessage (ctx, responseJson);
            } else {
                String responseJson = new ResponseJson ().success ().setData ("fromUserId", fromUserId).setData ("originalFilename", originalFilename)
                        .setData ("fileSize", fileSize).setData ("fileUrl", fileUrl).setData ("type", ChatType.FILE_MSG_SINGLE_SENDING).toString ();
                sendMessage (toUserCtx, responseJson);
            }
        } catch (Exception e) {
            e.printStackTrace ();
            LOGGER.error (e.getMessage ());
        }
    }

    /**
     *@Description: TODO(群组发送图片或者文件) 
     *@Author: wangchengjie
     *@Since: 2019年3月29日下午4:26:06
     *@param param
     *@param ctx
     */
    @Override
    public void FileMsgGroupSend(JSONObject param,ChannelHandlerContext ctx){
        try {
            String fromUserId = (String) param.get ("fromUserId");
            String toGroupId = (String) param.get ("toGroupId");
            String originalFilename = (String) param.get ("originalFilename");
            String fileSize = (String) param.get ("fileSize");
            String fileUrl = (String) param.get ("fileUrl");
            GroupInfo groupInfo = groupInfoService.getByGroupId (toGroupId);
            if (groupInfo == null) {
                String responseJson = new ResponseJson ().error ("该群id不存在").toString ();
                sendMessage (ctx, responseJson);
            } else {
                String responseJson = new ResponseJson ().success ().setData ("fromUserId", fromUserId).setData ("toGroupId", toGroupId)
                        .setData ("originalFilename", originalFilename).setData ("fileSize", fileSize).setData ("fileUrl", fileUrl)
                        .setData ("type", ChatType.FILE_MSG_GROUP_SENDING).toString ();
                groupInfo.getMembers ().stream ().forEach (member -> {
                    ChannelHandlerContext toCtx = Constant.onlineUserMap.get (member.getUserId ());
                    if (toCtx != null && !member.getUserId ().equals (fromUserId)) {
                        sendMessage (toCtx, responseJson);
                    }
                });
            }
        } catch (Exception e) {
            e.printStackTrace ();
            LOGGER.error (e.getMessage ());
        }
    }

    /**
     *@Description: TODO(消息类型不存在) 
     *@Author: wangchengjie
     *@Since: 2019年3月30日下午3:39:02
     *@param ctx
     */
    @Override
    public void typeError(ChannelHandlerContext ctx){
        try {
            String responseJson = new ResponseJson ().error ("该类型不存在！").toString ();
            sendMessage (ctx, responseJson);
        } catch (Exception e) {
            e.printStackTrace ();
            LOGGER.error (e.getMessage ());
        }
    }

    private void sendMessage(ChannelHandlerContext ctx,String message){
        ctx.channel ().writeAndFlush (new TextWebSocketFrame (message));
    }

}
